#include "Base.h"
#include <vector>
#include <string>
#include <map>

template<class T>
class CTemplatedVectorMapManager
{
public:
	class CMapResourceValue
	{
	public:

		T* m_Value;
		size_t m_Id;
		CMapResourceValue(T *Value, size_t Id): m_Value(Value), m_Id(Id){}
		CMapResourceValue(){}
	};
	
	
	typedef std::vector<T *> TVectorResources;
	typedef std::map<std::string, CMapResourceValue> TMapResources;


protected:


	TVectorResources m_ResourcesVector;
	TMapResources m_ResourcesMap;


public:
	CTemplatedVectorMapManager(){}
	virtual ~CTemplatedVectorMapManager(){ Destroy();}
	void RemoveResource(const std::string &Name)
	{
		TMapResources::iterator it=m_ResourcesMap.find(Name);
		if(it!=m_ResourcesMap.end()) 
		{
			size_t l_Id=it->second->m_Id;
			CHECKED_DELETE(it->second->m_Value);
			m_ResourcesMap.erare(it);
			m_ResourcesVector.erase(m_ResourcesVector.begin()+l_Id);
			for(TMapResources::iterator it2=m_ResourcesMap.begin(); it2!=m_ResourcesMap.end();++it2)
			{
				if(it2->second.m_Id>l_Id) --it2->second.m_Id;
			}
			release it->second;
		}
		
		else LOGGER->AddNewLog(ELL_ERROR, "No hay elementos con ese name");

	}

	virtual T * GetResourceById(size_t Id)
	{
		if(Id<m_ResourcesVector.size()) return m_ResourcesVector[Id];
		LOGGER->AddNewLog(ELL_ERROR, "El ID se sale del rango del vector");
		return NULL;
	}

	virtual T * GetResource(const std::string &Name)
	{
		TMapResources::iterator it=m_ResourcesMap.find(Name);
		if(it!=m_ResourcesMap.end()) return m_ResourcesMap[Name].m_Value;
		
		LOGGER->AddNewLog(ELL_ERROR, "No se encontro el resource en el mapa");
		return NULL;
	}
	
	virtual bool AddResource(const std::string &Name, T *Resource)
	{
		TMapResources::iterator it=m_ResourcesMap.find(Name);
		if(it==m_ResourcesMap.end()) 
		{
			m_ResourcesVector.push_back(Resource);
			m_ResourcesMap[Name]=CMapResourceValue(Resource,m_ResourcesVector.size()-1);
			return true;
		}
		LOGGER->AddNewLog(ELL_ERROR, "El Resource ya se encuentra agregado en el mapa");
		return false;
	}
	
	virtual void Destroy()
	{
		for(size_t i=0;i<m_ResourcesVector.size();++i)
		{
			CHECKED_DELETE(m_ResourcesVector[i]);
		}
		//CHECKED_RELEASE( m_ResourcesMap);
		//CHECKED_RELEASE(m_ResourcesVector);
	}
	
	TMapResources & GetResourcesMap()
	{
		return m_ResourcesMap;
	}
	
	TVectorResources & GetResourcesVector()
	{
		return m_ResourcesVector;
	}
};